package com.ys.controller.api.finance;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import javax.servlet.http.HttpServletRequest;

import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.ys.config.MenuId;
import com.ys.entity.finance.TcwProformaInvoice;
import com.ys.entity.finance.TcwProformaInvoiceItem;
import com.ys.entity.hr.ThrOperateCompanyApply;
import com.ys.entity.hr.ThrOperateRegistration;
import com.ys.entity.sys.YsCol;
import com.ys.mapper.business.DiySqlMapper;
import com.ys.service.sys.CommonApiService;
import com.ys.service.sys.PdfService;
import com.ys.service.sys.UploadService;
import com.ys.util.ExportExcelUtils;
import com.ys.util.dhecp.DateUtils;
import com.ys.vo.LayuiTableVoJA;
import com.ys.vo.R;

@Controller
@RequestMapping("/api/inter/tcwProformaInvoice")
public class ApiInterTcwProformaInvoiceController {

	private static final Logger logger = LoggerFactory.getLogger(ApiInterTcwProformaInvoiceController.class);

	@Autowired
	private CommonApiService<TcwProformaInvoice> commonApiService;

	@Autowired
	private PdfService pdfService;

	@Autowired
	private DiySqlMapper diySqlMapper;


	@RequiresPermissions("tcwProformaInvoice:view")
	@RequestMapping("/search")
    @ResponseBody
	public LayuiTableVoJA search(@ModelAttribute TcwProformaInvoice cond){
		cond.addLeftJoin("THR_OperateCompanyApply THRO ON THRO.vgsbm = A.vgsbmBuy ")
				.addField("THRO.vGsSh AS vGsShBuy,THRO.CUser AS cUser,THRO.vgsMc AS vgsMcBuy");//购买方公司
		cond.addLeftJoin("TB_CompanyInfo D ON D.vid = A.vgsbmSales ")
				.addField("D.tax AS vGsShSales,D.vname AS vnameSales");//销售公司
		cond = commonApiService.dataAuth(MenuId.TCW_ProformaInvoice, cond);
		return commonApiService.searchLay(cond);
	}
	

	@RequestMapping("/export")
	@ResponseBody
	public R export(@ModelAttribute TcwProformaInvoice cond, String conditions){
		try {
			cond.setPage(0).setSize(999999);
			cond.addLeftJoin("THR_OperateCompanyApply THRO ON THRO.vgsbm = A.vgsbmBuy ")
					.addField("THRO.vGsSh AS vGsShBuy,THRO.CUser AS cUser,THRO.vgsMc AS vgsMcBuy");//购买方公司
			cond.addLeftJoin("TB_CompanyInfo D ON D.vid = A.vgsbmSales ")
					.addField("D.tax AS vGsShSales,D.vname AS vnameSales");//销售公司
			cond = commonApiService.dataAuth(MenuId.TCW_ProformaInvoice, cond);

			//获取菜单字段数据
			List<YsCol> listField = new YsCol()
					.setMenuId(MenuId.TCW_ProformaInvoice)
					.where("A.Code != 'ope'")
					.setFrontShow(1)
					.setOrderby("A.SortNo asc")
					.queryList();
			//获取数据
			List<Map<String, Object>> listData = cond.queryMap();
			//处理数据
			ExportExcelUtils<ThrOperateRegistration> util = new ExportExcelUtils<>(new ThrOperateRegistration());
			String toFilePath = util.exportExcel(listData, listField, "运营形式发票开票单");
			UploadService.UploadDto dto = commonApiService.uploadLocalToServer(toFilePath);
			return R.ok(dto.getUrl());
		}catch (Exception e){
			logger.error("导出出错：",e.getMessage(),e);
			return R.error("导出失败，请稍后重试！");
		}
	}

	/**
	 * 打印销售发票
	 * @param request
	 * @param bid
	 * @return
	 * @throws Exception
	 */
	@RequestMapping("/exportdyxs")
	@ResponseBody
	public R exportdyxs(HttpServletRequest request,@RequestParam("bid") String bid) throws Exception{
		//查询形式发票数据
		TcwProformaInvoice tcwProformaInvoice = new TcwProformaInvoice().setBid(bid).queryFirst();
		//产品数组
		List<PdfService.ProductDto> listData = new ArrayList<>();
		//获取发票日期的上一月时间
		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM");
		Date date = dateFormat.parse(tcwProformaInvoice.getInvoiceMonth());
		Calendar calendar = Calendar.getInstance();
		//设置时间
		calendar.setTime(date);
		// 设置为当前月的第一天
		calendar.set(Calendar.DAY_OF_MONTH, 1);
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);

		String startTimeStr = DateUtils.convertDateToTDate(calendar.getTime());

		calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
		calendar.set(Calendar.HOUR_OF_DAY, 23);
		calendar.set(Calendar.MINUTE, 59);
		calendar.set(Calendar.SECOND, 59);
		calendar.set(Calendar.MILLISECOND, 999);
		String endTimeStr = DateUtils.convertDateToTDate(calendar.getTime());

		BigDecimal amount = BigDecimal.ZERO;
		//查询这个公司下的采购订单信息
		List<Map<String, Object>> purchaseOrderSonList = diySqlMapper.getPurchaseOrderSonList(tcwProformaInvoice.getVgsbmBuy(), startTimeStr, endTimeStr);
		for (Map<String, Object> purchaseMap : purchaseOrderSonList){
			//单价*数量
			amount = new BigDecimal(purchaseMap.get("sum").toString()).multiply(new BigDecimal(purchaseMap.get("price2").toString()));
			listData.add(new PdfService.ProductDto(purchaseMap.get("sCode").toString(),purchaseMap.get("sName").toString(),purchaseMap.get("sum").toString()
					,"件",purchaseMap.get("price2").toString(),amount.toString()));
			amount = amount.add(amount);
		}
		//查询公司报错的数据
		List<Map<String, Object>> purchasingErrorList = diySqlMapper.getPurchasingErrorList(tcwProformaInvoice.getVgsbmBuy(), startTimeStr, endTimeStr);
		for (Map<String, Object> purchasingErrorMap : purchasingErrorList){
			//单价*数量
			listData.add(new PdfService.ProductDto(purchasingErrorMap.get("sCode").toString(),purchasingErrorMap.get("sName").toString(),purchasingErrorMap.get("sum").toString()
					,"件",purchasingErrorMap.get("price2").toString(),purchasingErrorMap.get("amount").toString()));
			amount = amount.add(new BigDecimal(purchasingErrorMap.get("amount").toString()));

		}

		//查询运营公司信息
		ThrOperateCompanyApply thrOperateCompanyApply = new ThrOperateCompanyApply().setVgsbm(tcwProformaInvoice.getVgsbmBuy()).setOperationsAttribute(2).queryFirst();
		String url = pdfService.generatePDF_XSFP("问前集团控股有限公司","WEN QIAN GROUP HOLDINGS LIMITED",thrOperateCompanyApply.getVgsmc(),
				tcwProformaInvoice.getInvoiceNumber(), amount.toString(),tcwProformaInvoice.getInvoiceDate(),"CHINA",tcwProformaInvoice.getVgsbmBuy(),listData);

		return R.ok(url);
	}

	/**
	 * 打印服务发票
	 * @param request
	 * @param bid
	 * @return
	 * @throws Exception
	 */
	@RequestMapping("/exportdyfw")
	@ResponseBody
	public R exportdyfw(HttpServletRequest request,@RequestParam("bid") String bid) throws Exception{
		//查询形式发票数据
		TcwProformaInvoice tcwProformaInvoice = new TcwProformaInvoice().setBid(bid).queryFirst();
		//产品数组
		List<PdfService.SaleDto> listData = new ArrayList<>();
		List<TcwProformaInvoiceItem> tcwProformaInvoiceItemList = new TcwProformaInvoiceItem()
				.setProformaInvoiceBid(tcwProformaInvoice.getBid())
				.where("A.Vname != '采购服务→采购成本' AND A.Vname != '采购服务→代理采购服务费'")
				.queryList();
		Map<String, BigDecimal> ageGroup = tcwProformaInvoiceItemList.stream().collect(Collectors.groupingBy(TcwProformaInvoiceItem::getVname
				, Collectors.collectingAndThen(Collectors.toList()
						, x -> x.stream().map(TcwProformaInvoiceItem::getVamount).reduce(BigDecimal.ZERO, BigDecimal::add))));

		//总金额
		BigDecimal tolAmount = BigDecimal.ZERO;
		//仓储服务 = 仓储服务→仓储费  + 仓储服务→经营理赔款项；
		BigDecimal ccfwAmount = BigDecimal.ZERO;
		ccfwAmount = ageGroup.get("仓储服务→仓储费")
				.add(ageGroup.get("仓储服务→经营理赔款项"));
		listData.add(new PdfService.SaleDto(tcwProformaInvoice.getInvoiceDate()+"仓储服务","1","套",ccfwAmount.toString(),ccfwAmount.toString()));
		tolAmount = tolAmount.add(ccfwAmount);

		//组装等服务 = 仓储服务→手续费 + 仓储服务→透明计划贴标费 + 仓储服务→纸箱费 + 仓储服务→组装费 + 组装服务→经营理赔款项
		BigDecimal zzfwAmount = BigDecimal.ZERO;
		zzfwAmount = ageGroup.get("仓储服务→手续费")
				.add(ageGroup.get("仓储服务→透明计划贴标费"))
				.add(ageGroup.get("仓储服务→纸箱费"))
				.add(ageGroup.get("仓储服务→组装费"))
				.add(ageGroup.get("组装服务→经营理赔款项"));
		listData.add(new PdfService.SaleDto(tcwProformaInvoice.getInvoiceDate()+"组装等服务","1","套",zzfwAmount.toString(),zzfwAmount.toString()));
		tolAmount = tolAmount.add(zzfwAmount);

		//国际货物运输代理服务 = 物流服务→头程运费 + 物流服务→经营理赔款项
		BigDecimal gjfwAmount = BigDecimal.ZERO;
		gjfwAmount = ageGroup.get("物流服务→头程运费")
				.add(ageGroup.get("物流服务→经营理赔款项"));
		listData.add(new PdfService.SaleDto(tcwProformaInvoice.getInvoiceDate()+"国际货物运输代理服务","1","套",gjfwAmount.toString(),gjfwAmount.toString()));
		tolAmount = tolAmount.add(gjfwAmount);

		//信息技术服务 = 产品服务→产品开发费 + 运营服务→VAT注册费及续期服务费 + 运营服务→经营理赔款项 + 运营服务→云服务器
		//+运营服务→资源占用费 + 运营服务→商标专利注册 + 运营服务→软件开户费 + 产品服务→美工费用 + 运营服务→管理绩效
		//+运营服务→管理绩效分配 + 运营服务→手续费 + 信息服务→经营理赔款项
		BigDecimal xxjsfwAmount = BigDecimal.ZERO;
		xxjsfwAmount = ageGroup.get("产品服务→产品开发费")
				.add(ageGroup.get("运营服务→VAT注册费及续期服务费"))
				.add(ageGroup.get("运营服务→经营理赔款项"))
				.add(ageGroup.get("运营服务→云服务器"))
				.add(ageGroup.get("运营服务→资源占用费"))
				.add(ageGroup.get("运营服务→商标专利注册"))
				.add(ageGroup.get("运营服务→软件开户费"))
				.add(ageGroup.get("产品服务→美工费用"))
				.add(ageGroup.get("运营服务→管理绩效"))
				.add(ageGroup.get("运营服务→管理绩效分配"))
				.add(ageGroup.get("运营服务→手续费"))
				.add(ageGroup.get("信息服务→经营理赔款项"))
		;
		listData.add(new PdfService.SaleDto(tcwProformaInvoice.getInvoiceDate()+"信息技术服务","1","套",xxjsfwAmount.toString(),xxjsfwAmount.toString()));
		tolAmount = tolAmount.add(xxjsfwAmount);

		//查询运营公司信息
		ThrOperateCompanyApply thrOperateCompanyApply = new ThrOperateCompanyApply().setVgsbm(tcwProformaInvoice.getVgsbmBuy()).setOperationsAttribute(2).queryFirst();
		String url = pdfService.generatePDF_FWFP("问前集团控股有限公司","WEN  QIAN  GROUP  HOLDINGS  LIMITED",thrOperateCompanyApply.getVgsmc(),
				tcwProformaInvoice.getInvoiceNumber(), String.valueOf(tolAmount),tcwProformaInvoice.getInvoiceDate(),"CHINA",tcwProformaInvoice.getVgsbmBuy(),listData);

		return R.ok(url);
	}
}
